package com.coderyuan.utils;

import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import com.coderyuan.stream.StreamUtil;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;

/**
 * 提供当前app的资源
 */
public class ResourcesManager {

    private static final String TAG = ResourcesManager.class.getSimpleName();

    private static final String SYS_PACKAGE_NAME = "android";
    private static final Resources sSysRes = Resources.getSystem();
    private static final DisplayMetrics DISPLAY_METRICS = sSysRes.getDisplayMetrics();

    private static Context sAppContext;
    private static Resources sRes;
    private static String sPackageName;
    private static AssetManager sAssetManager;

    public static void init(Context context) {
        sAppContext = context;
        sRes = context.getResources();
        sPackageName = context.getPackageName();
        sAssetManager = context.getAssets();
    }

    public static Context getAppContext() {
        return sAppContext;
    }

    public static Resources getResources() {
        return sRes;
    }

    public static int getAnimId(String name) {
        return sRes.getIdentifier(name, "anim", sPackageName);
    }

    public static int getDimenId(String name) {
        return sRes.getIdentifier(name, "dimen", sPackageName);
    }

    public static int getDimensionPixelSize(String name) {
        int id = getDimenId(name);
        return sRes.getDimensionPixelSize(id);
    }

    public static int getViewId(String name) {
        return sRes.getIdentifier(name, "id", sPackageName);
    }

    public static int getLayoutId(String name) {
        return sRes.getIdentifier(name, "layout", sPackageName);
    }

    public static int getDrawableId(String name) {
        return sRes.getIdentifier(name, "drawable", sPackageName);
    }

    public static Drawable getDrawable(String name) {
        int id = getDrawableId(name);
        return sRes.getDrawable(id);
    }

    public static int getStyleId(String name) {
        return sRes.getIdentifier(name, "style", sPackageName);
    }

    public static int getColor(int id) {
        return sRes.getColor(id);
    }

    public static int getColor(String name) {
        int id = sRes.getIdentifier(name, "color", sPackageName);
        return sRes.getColor(id);
    }

    public static CharSequence getText(int resId) {
        return sRes.getText(resId);
    }

    public static String getString(int id) {
        return sRes.getString(id);
    }

    public static String getString(int id, Object...formatArgs) {
        return sRes.getString(id, formatArgs);
    }

    public static String getString(String name) {
        int id = getStringId(name);
        return sRes.getString(id);
    }

    public static String getString(String name, Object...formatArgs) {
        int id = getStringId(name);
        return sRes.getString(id, formatArgs);
    }

    public static String[] getStringArray(int id) {
        return sRes.getStringArray(id);
    }

    public static int getStringId(String name) {
        return sRes.getIdentifier(name, "string", sPackageName);
    }

    public static View findViewByIdName(View v, String name) {
        int id = getViewId(name);
        return v.findViewById(id);
    }

    /**
     * Inflate a view from an XML resource.
     */
    public static View inflateView(String layoutName) {
        return View.inflate(sAppContext, getLayoutId(layoutName), null);
    }

    public static Typeface createFromAsset(String path) {
        return Typeface.createFromAsset(sAssetManager, path);
    }

    public static InputStream openAssetFile(String assetPath) {
        try {
            return sAssetManager.open(assetPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static long getAssetFileSize(String name) {
        InputStream in = openAssetFile(name);
        if (in != null) {
            try {
                return in.available();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                StreamUtil.closeQuietly(in);
            }
        }
        return -1;
    }

    public static Bitmap getAssetBitmap(String assetPath) {
        if (TextUtils.isEmpty(assetPath)) {
            return null;
        }
        InputStream is = openAssetFile(assetPath);
        Bitmap bitmap = BitmapFactory.decodeStream(is);
        StreamUtil.closeQuietly(is);
        return bitmap;
    }

    public static boolean copyAssetFile(String name, String dest) {
        return copyAssetFile(name, new File(dest));
    }

    public static boolean copyAssetFile(String name, File file) {
        InputStream in = openAssetFile(name);
        if (in == null) {
            return false;
        }
        try {
            StreamUtil.copyStream(in, file);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            StreamUtil.closeQuietly(in);
        }
        return false;
    }

    /**
     * Read a raw file from the android application package
     * 
     * @param resId The resource ID to read
     * @return The whole file in a string
     */
    public static String readRawFile(int resId) {
        Log.d(TAG, "Fetching raw file with id: " + resId);
        InputStream is = sRes.openRawResource(resId);
        try {
            return StreamUtil.loadContent(is);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            StreamUtil.closeQuietly(is);
        }
        return null;
    }

    /**
     * Update the application locale based on the language
     * 
     * @param activity
     * @param language
     */
    public static void updateLocale(String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
        Configuration configuration = new Configuration();
        configuration.locale = locale;
        sRes.updateConfiguration(configuration, sRes.getDisplayMetrics());
    }

    /**
     * This method converts dp unit to equivalent pixels, depending on device density. NEEDS UTILS TO BE INITIALIZED
     * BEFORE USAGE.
     * 
     * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
     * @return A float value to represent px equivalent to dp depending on device density
     */
    public static float dipToPixel(int value) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, DISPLAY_METRICS);
    }

    public static boolean isHardwareAccelerated(Canvas canvas) {
        if (Build.VERSION.SDK_INT >= 11) {
            try {
                return (Boolean) Canvas.class.getDeclaredMethod("isHardwareAccelerated").invoke(canvas);
            } catch (Exception e) {
            }
        }
        return false;
    }

    /**
     * 用于获取状态栏的高度。
     * 
     * @return 返回状态栏高度的像素值。
     */
    public static int getStatusBarHeight() {
        int id = sSysRes.getIdentifier("status_bar_height", "dimen", "android");
        return sSysRes.getDimensionPixelSize(id);
    }

    private static int getSysIdentifier(String name, String defType) {
        return sSysRes.getIdentifier(name, defType, SYS_PACKAGE_NAME);
    }

    public static int getSysDrawableId(String name) {
        return getSysIdentifier(name, "drawable");
    }

    public static Drawable getSysDrawable(String name) {
        return sSysRes.getDrawable(getSysDrawableId(name));
    }

    public static int getSysLayoutId(String name) {
        return getSysIdentifier(name, "layout");
    }

    public static int getSysColorId(String name) {
        return getSysIdentifier(name, "color");
    }
}
